/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.miit.elearning.hibernate.dao;

import java.util.List;
import org.hibernate.Session;
import ru.miit.elearning.hibernate.dto.AdditionalProperty;
import ru.miit.elearning.hibernate.dto.CurriculumLevel;
import ru.miit.elearning.hibernate.dto.CurriculumProperty;
import ru.miit.elearning.hibernate.dto.CurriculumPropertyId;
import ru.miit.elearning.hibernate.dto.Plugin;
import ru.miit.elearning.hibernate.dto.PropertyType;
import ru.miit.elearning.hibernate.dto.UserProperty;
import ru.miit.elearning.hibernate.dto.UserPropertyId;

/**
 *
 * @author Cyclone
 */
public class ConfigurationDAO extends GenericDAO {


    /* ================ COMMON SECTION ====================================== */
    public static final String ALIAS_VIRTUAL_TUTOR_IBM = "vtutoribm", ALIAS_ZOS_HOME_FOLDER = "zoshomefolder";

    public ConfigurationDAO(Session session) {
        super(session);
    }

    public List<AdditionalProperty> findUserProperties() {
        return findAdditionalProperties(PROPERTY_TYPE_USER);
    }

    public List<AdditionalProperty> findCurriculumProperties() {
        return findAdditionalProperties(PROPERTY_TYPE_CURRICULUM);
    }

    public List<AdditionalProperty> findAdditionalProperties(int propertyType) {
        return session.createQuery("FROM AdditionalProperty ap WHERE ap.propertyType.idPropertyType = :curriculumPropertyType").setParameter("curriculumPropertyType", propertyType).list();
    }

    public List<AdditionalProperty> findCurriculumPropertiesByNoCurriculum(int curriculumId) {
        return session.createQuery("from AdditionalProperty ap "
                + "WHERE ap.propertyType.idPropertyType = :curriculumPropertyType "
                + "AND ap.idAdditionalProperty not in "
                + "(SELECT cp.id.idAdditionalProperty FROM CurriculumProperty cp WHERE cp.id.idCurriculumLevel = :curriculumId)").setParameter("curriculumPropertyType", PROPERTY_TYPE_CURRICULUM).setParameter("curriculumId", curriculumId).list();
    }

    public List<AdditionalProperty> findUserPropertiesByNoUser(int userId) {
        // new UserProperty().getId().getIdUser();
        return session.createQuery("from AdditionalProperty ap "
                + "WHERE ap.propertyType.idPropertyType = :userPropertyType "
                + "AND ap.idAdditionalProperty not in "
                + "(SELECT up.id.idAdditionalProperty FROM UserProperty up WHERE up.id.idUser = :userId)").setParameter("userPropertyType", PROPERTY_TYPE_USER).setParameter("userId", userId).list();
    }

    public AdditionalProperty addProperty(String name, String description, int propertyType, boolean valueNeeded, String alias) {
        AdditionalProperty property = new AdditionalProperty();

        property.setName(name);
        property.setDescription(description);
        property.setPropertyType((PropertyType) session.get(PropertyType.class, propertyType));
        property.setValueNeeded(valueNeeded);
        property.setAlias(alias);
        int id = (Integer) session.save(property);

        return (AdditionalProperty) session.get(AdditionalProperty.class, id);
    }

    public String deleteProperty(int propertyId) {
        AdditionalProperty property = (AdditionalProperty) session.get(AdditionalProperty.class, propertyId);
        String name = property.getName();
        session.delete(property);
        return name;
    }

    public void setCurriculumProperty(int courseId, int propertyId, String value) {
        CurriculumProperty cp = new CurriculumProperty();
        //cp.setAdditionalProperty((AdditionalProperty)session.get(AdditionalProperty.class, propertyId));
        //cp.setCurriculumLevel((CurriculumLevel)session.get(CurriculumLevel.class, courseId));
        cp.setId(new CurriculumPropertyId(propertyId, courseId));
        cp.setValue(value);

        session.saveOrUpdate(cp);
    }

    public void deleteCurriculumProperty(int courseId, int propertyId) {
        CurriculumProperty cp = (CurriculumProperty) session.get(CurriculumProperty.class, new CurriculumPropertyId(propertyId, courseId));
        session.delete(cp);
    }

    public void setUserProperty(int userId, int propertyId, String value) {
        UserProperty up = new UserProperty();

        up.setId(new UserPropertyId(userId, propertyId));
        up.setValue(value);

        session.saveOrUpdate(up);
    }

    public void deleteUserProperty(int userId, int propertyId) {
        UserProperty up = (UserProperty) session.get(UserProperty.class, new UserPropertyId(userId, propertyId));
        session.delete(up);
    }

    public List<PropertyType> findAllPropertyTypes() {
        return session.createQuery("from PropertyType").list();
    }

    public AdditionalProperty findAdditionalProperty(int propertyId) {
        return (AdditionalProperty) session.get(AdditionalProperty.class, propertyId);
    }

    public String findUserPropertyValue(int propertId, int userId) {
        UserProperty up = (UserProperty) session.get(UserProperty.class, new UserPropertyId(userId, propertId));
        return up.getValue();
    }

    public String findUserPropertyValueByAlias(int userId, String alias) {
        String value = null;
        try {
            AdditionalProperty ap = (AdditionalProperty) session.createQuery("from AdditionalProperty ap WHERE ap.alias = :alias").setParameter("alias", alias).uniqueResult();
            if (ap != null) {
                UserProperty up = (UserProperty) session.get(UserProperty.class, new UserPropertyId(userId, ap.getIdAdditionalProperty()));
                if (up != null) {
                    value = up.getValue();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    public String findCurriculumPropertyValueByAlias(int courseId, String alias) {

        AdditionalProperty ap = (AdditionalProperty) session.createQuery("from AdditionalProperty ap WHERE ap.alias = :alias").setParameter("alias", alias).uniqueResult();
        int apId = ap.getIdAdditionalProperty();

        return ((CurriculumProperty) session.get(CurriculumProperty.class, new CurriculumPropertyId(apId, courseId))).getValue();
    }

    public void updateAdditionalProperty(int propertyId, int propertyType, String title, boolean valueNeeded, String description, String alias) {
        AdditionalProperty ap = (AdditionalProperty) session.get(AdditionalProperty.class, propertyId);
        ap.setPropertyType(((PropertyType) session.get(PropertyType.class, propertyType)));
        ap.setName(title);
        ap.setValueNeeded(valueNeeded);
        ap.setDescription(description);
        ap.setAlias(alias);

        session.save(ap);
    }

//    public List<AdditionalProperty> findAllProperties() {
//        return session.createQuery("FROM AdditionalProperty").list();
//    }
    public List<Plugin> findAllPlugins() {
        return session.createQuery("FROM Plugin").list();
    }

    public Plugin findPlugin(int id) {
        return (Plugin) session.get(Plugin.class, id);
    }

    public String deletePlugin(int id) {
        String name = null;
        Plugin p = findPlugin(id);
        name = p.getName();
        session.delete(p);
        return name;
    }

    public Plugin updatePlugin(int id, String name, boolean enable, int property, int initType, String initiate, String description) {
        Plugin p = findPlugin(id);
        p.setName(name);
        p.setEnable(enable);
        p.setAdditionalProperty(findAdditionalProperty(property));
        p.setInitType(initType);
        p.setInitiate(initiate);
        p.setDescription(description);

        session.save(p);

        return p;
    }

    public Plugin addPlugin(String name, boolean enable, int property, int initType, String initiate, String description) {
        Plugin p = new Plugin();
        p.setName(name);
        p.setEnable(enable);
        p.setAdditionalProperty(findAdditionalProperty(property));
        p.setInitType(initType);
        p.setInitiate(initiate);
        p.setDescription(description);

        session.save(p);

        return p;
    }
}
